package com.mall.gateway.fallback;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * 服务降级处理
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class HystrixFallbackHandler implements HandlerFunction<ServerResponse> {

    private final ObjectMapper objectMapper;

    @Override
    public Mono<ServerResponse> handle(ServerRequest request) {
        String path = request.path();
        log.error("服务调用失败，地址：{}", path);
        
        return ServerResponse
                .status(HttpStatus.SERVICE_UNAVAILABLE)
                .contentType(MediaType.APPLICATION_JSON)
                .body(Mono.fromSupplier(() -> {
                    try {
                        Map<String, Object> result = new HashMap<>();
                        result.put("code", HttpStatus.SERVICE_UNAVAILABLE.value());
                        result.put("message", "服务繁忙，请稍后再试");
                        result.put("path", path);
                        result.put("success", false);
                        
                        return objectMapper.writeValueAsString(result);
                    } catch (JsonProcessingException e) {
                        log.error("回退处理异常", e);
                        return "{\"code\":503,\"message\":\"服务暂时不可用\"}";
                    }
                }), String.class);
    }
    
    /**
     * 写入响应
     */
    public Mono<Void> fallbackResponse(ServerHttpResponse response, String path) {
        response.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        
        Map<String, Object> result = new HashMap<>();
        result.put("code", HttpStatus.SERVICE_UNAVAILABLE.value());
        result.put("message", "服务繁忙，请稍后再试");
        result.put("path", path);
        result.put("success", false);
        
        try {
            byte[] bytes = objectMapper.writeValueAsBytes(result);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        } catch (JsonProcessingException e) {
            log.error("回退响应处理异常", e);
            return Mono.error(e);
        }
    }
} 